/**
 * Created by PanJiaChen on 16/11/18.
 */

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string | null}
 */
import Clipboard from 'clipboard';
import store from '@/store/index';
import { downloadPlaylet } from '@/api/content';
import { paymentList } from '@/api/payment';

let oldpayInfo = {};
let newpayInfo = {};
let new_play_ids = [];
let mini_app_id = window.localStorage.getItem('mini_app_id');
export function parseTime(time, cFormat) {
  if (arguments.length === 0 || !time) {
    return null;
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}';
  let date;
  if (typeof time === 'object') {
    date = time;
  } else {
    if (typeof time === 'string') {
      if (/^[0-9]+$/.test(time)) {
        // support "1548221490638"
        time = parseInt(time);
      } else {
        // support safari
        // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
        time = time.replace(new RegExp(/-/gm), '/');
      }
    }
    if (typeof time === 'number' && time.toString().length === 10) {
      time *= 1000;
    }
    date = new Date(time);
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay(),
  };
  const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
    const value = formatObj[key];
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value];
    }
    return value.toString().padStart(2, '0');
  });
  return time_str;
}

/**
 * @param {number} time
 * @param {string} option
 * @returns {string}
 */
export function formatTime(time, option) {
  if (`${time}`.length === 10) {
    time = parseInt(time) * 1000;
  } else {
    time = +time;
  }
  const d = new Date(time);
  const now = Date.now();

  const diff = (now - d) / 1000;

  if (diff < 30) {
    return '刚刚';
  }
  if (diff < 3600) {
    // less 1 hour
    return `${Math.ceil(diff / 60)}分钟前`;
  }
  if (diff < 3600 * 24) {
    return `${Math.ceil(diff / 3600)}小时前`;
  }
  if (diff < 3600 * 24 * 2) {
    return '1天前';
  }
  if (option) {
    return parseTime(time, option);
  }
  return `${d.getMonth() + 1}月${d.getDate()}日${d.getHours()}时${d.getMinutes()}分`;
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function getQueryObject(url) {
  url = url == null ? window.location.href : url;
  const search = url.substring(url.lastIndexOf('?') + 1);
  const obj = {};
  const reg = /([^?&=]+)=([^?&=]*)/g;
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1);
    let val = decodeURIComponent($2);
    val = String(val);
    obj[name] = val;
    return rs;
  });
  return obj;
}

/**
 * @param {string} input value
 * @returns {number} output value
 */
export function byteLength(str) {
  // returns the byte length of an utf8 string
  let s = str.length;
  for (let i = str.length - 1; i >= 0; i--) {
    const code = str.charCodeAt(i);
    if (code > 0x7f && code <= 0x7ff) s++;
    else if (code > 0x7ff && code <= 0xffff) s += 2;
    if (code >= 0xdc00 && code <= 0xdfff) i--;
  }
  return s;
}

/**
 * @param {Array} actual
 * @returns {Array}
 */
export function cleanArray(actual) {
  const newArray = [];
  for (let i = 0; i < actual.length; i++) {
    if (actual[i]) {
      newArray.push(actual[i]);
    }
  }
  return newArray;
}

/**
 * @param {Object} json
 * @returns {Array}
 */
export function param(json) {
  if (!json) return '';
  return cleanArray(
    Object.keys(json).map((key) => {
      if (json[key] === undefined) return '';
      return `${encodeURIComponent(key)}=${encodeURIComponent(json[key])}`;
    }),
  ).join('&');
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function param2Obj(url) {
  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ');
  if (!search) {
    return {};
  }
  const obj = {};
  const searchArr = search.split('&');
  searchArr.forEach((v) => {
    const index = v.indexOf('=');
    if (index !== -1) {
      const name = v.substring(0, index);
      const val = v.substring(index + 1, v.length);
      obj[name] = val;
    }
  });
  return obj;
}

/**
 * @param {string} val
 * @returns {string}
 */
export function html2Text(val) {
  const div = document.createElement('div');
  div.innerHTML = val;
  return div.textContent || div.innerText;
}

/**
 * Merges two objects, giving the last one precedence
 * @param {Object} target
 * @param {(Object|Array)} source
 * @returns {Object}
 */
export function objectMerge(target, source) {
  if (typeof target !== 'object') {
    target = {};
  }
  if (Array.isArray(source)) {
    return source.slice();
  }
  Object.keys(source).forEach((property) => {
    const sourceProperty = source[property];
    if (typeof sourceProperty === 'object') {
      target[property] = objectMerge(target[property], sourceProperty);
    } else {
      target[property] = sourceProperty;
    }
  });
  return target;
}

/**
 * @param {HTMLElement} element
 * @param {string} className
 */
export function toggleClass(element, className) {
  if (!element || !className) {
    return;
  }
  let classString = element.className;
  const nameIndex = classString.indexOf(className);
  if (nameIndex === -1) {
    classString += `${className}`;
  } else {
    classString = classString.substr(0, nameIndex) + classString.substr(nameIndex + className.length);
  }
  element.className = classString;
}

/**
 * @param {string} type
 * @returns {Date}
 */
export function getTime(type) {
  if (type === 'start') {
    return new Date().getTime() - 3600 * 1000 * 24 * 90;
  }
  return new Date(new Date().toDateString());
}

/**
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export function debounce(func, wait, immediate) {
  let timeout;
  let args;
  let context;
  let timestamp;
  let result;

  const later = function () {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp;

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last);
    } else {
      timeout = null;
      // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args);
        if (!timeout) context = args = null;
      }
    }
  };

  return function (...args) {
    context = this;
    timestamp = +new Date();
    const callNow = immediate && !timeout;
    // 如果延时不存在，重新设定延时
    if (!timeout) timeout = setTimeout(later, wait);
    if (callNow) {
      result = func.apply(context, args);
      context = args = null;
    }

    return result;
  };
}

/**
 * This is just a simple version of deep copy
 * Has a lot of edge cases bug
 * If you want to use a perfect deep copy, use lodash's _.cloneDeep
 * @param {Object} source
 * @returns {Object}
 */
export function deepClone(source) {
  if (!source && typeof source !== 'object') {
    throw new Error('error arguments', 'deepClone');
  }
  const targetObj = source.constructor === Array ? [] : {};
  Object.keys(source).forEach((keys) => {
    if (source[keys] && typeof source[keys] === 'object') {
      targetObj[keys] = deepClone(source[keys]);
    } else {
      targetObj[keys] = source[keys];
    }
  });
  return targetObj;
}

/**
 * @param {Array} arr
 * @returns {Array}
 */
export function uniqueArr(arr) {
  return Array.from(new Set(arr));
}

/**
 * @returns {string}
 */
export function createUniqueString() {
  const timestamp = `${+new Date()}`;
  const randomNum = `${parseInt((1 + Math.random()) * 65536)}`;
  return (+(randomNum + timestamp)).toString(32);
}

/**
 * Check if an element has a class
 * @param {HTMLElement} elm
 * @param {string} cls
 * @returns {boolean}
 */
export function hasClass(ele, cls) {
  return !!ele.className.match(new RegExp(`(\\s|^)${cls}(\\s|$)`));
}

/**
 * Add class to element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function addClass(ele, cls) {
  if (!hasClass(ele, cls)) ele.className += ` ${cls}`;
}

/**
 * Remove class from element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function removeClass(ele, cls) {
  if (hasClass(ele, cls)) {
    const reg = new RegExp(`(\\s|^)${cls}(\\s|$)`);
    ele.className = ele.className.replace(reg, ' ');
  }
}

export function formatTreeRole(data = []) {
  const treeData = deepClone(data);
  const level1 = treeData.filter((item) => item.level_num === '1');
  const level2 = treeData.filter((item) => item.level_num === '2');
  const level3 = treeData.filter((item) => item.level_num === '3');
  level3.map((item) => {
    const roledata = level2.find((role) => role.id === item.pid);
    if (roledata) {
      !roledata.children && (roledata.children = []);
      roledata.children.push(item);
    }
  });
  level2.map((item) => {
    const roledata = level1.find((role) => role.id === item.pid);
    if (roledata) {
      !roledata.children && (roledata.children = []);
      roledata.children.push(item);
    }
  });
  return level1;
}
// 视频上传限制
export function uploadVideoBefore(file, _this) {
  let isVideo = null;
  ['video/mp4'].includes(file.type) ? (isVideo = true) : (isVideo = false);
  const isLt2M = file.size / 1024 / 1024 < 20;
  if (!isVideo) {
    _this.$message.error('视频格式只支持mp4!');
  }
  if (!isLt2M) {
    _this.$message.error('上传视频大小不能超过 20MB!');
  }

  return isVideo && isLt2M;
}
// 上传图片校验
export function uploadImageBefore(file, _this, imageWidth, imageHeight) {
  let isImg = null;
  const suffix = file.name.split('.')[file.name.split('.').length - 1];
  ['jpg', 'jpeg', 'png', 'gif'].includes(suffix) ? (isImg = true) : (isImg = false);
  const isLt2M = file.size / 1024 / 1024 < 10;
  if (!isImg) {
    _this.$message.error('图片格式只支持jpg，jpeg,png,gif!');
    return false;
  }
  if (!isLt2M) {
    _this.$message.error('上传图片大小不能超过 10MB!');
    return false;
  }
  return isImg && isLt2M;
}

export function randomStr(len) {
  const le = len || 32;
  const $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; // ****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****
  const maxPos = $chars.length;
  let str = '';
  for (let i = 0; i < le; i++) {
    str += $chars.charAt(Math.floor(Math.random() * maxPos));
  }
  return str;
}
export const getFileNameUUID = () => {
  function rx() {
    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
  }
  return `${+new Date()}_${rx()}${rx()}`;
};
export const setMiniAppId = (data) => {
  mini_app_id = data;
};

export const getMiniAppId = (data) => {
  if (!data) {
    return { mini_app_id };
  }
  if (mini_app_id && mini_app_id !== '' && (!data.mini_app_id || data.mini_app_id.length === 0)) {
    // 数组情况
    if (JSON.stringify(data.mini_app_id) === '[]') {
      data.mini_app_id = [];
    } else if (!data.mini_app_id) {
      data.mini_app_id = mini_app_id;
    } else {
      data.mini_app_id = '';
    }
  }
  return data;
};

export function removeDp(arr1, arr2, id) {
  let arr;
  arr2 ? (arr = arr1.concat(arr2)) : (arr = arr1);
  const obj = {};
  console.log(arr2);
  const newArray = arr.reduce((pre, cur) => {
    if (!obj[cur[id]]) {
      obj[cur[id]] = true;
      pre.push(cur);
    }
    pre.sort((a, b) => a.chapter_num - b.chapter_num);
    return pre;
  }, []);
  return newArray;
}
export function getTimeVideo(time) {
  // 转换为式分秒
  let h = parseInt((time / 60 / 60) % 24);
  h = h < 10 ? `0${h}` : h;
  let m = parseInt((time / 60) % 60);
  m = m < 10 ? `0${m}` : m;
  let s = parseInt(time % 60);
  s = s < 10 ? `0${s}` : s;
  // 作为返回值返回
  return `${h}:${m}:${s}`;
}

export function formatNumber(str) {
  str = str || 0;
  if (str.toString().indexOf(',') === -1) {
    str = Number(str);
    const type = Object.prototype.toString.call(str);
    if (type === '[object Number]') {
      return str.toString().replace(/(^|\s)\d+/g, (m) => m.replace(/(?=(?!\b)(\d{3})+$)/g, ','));
    }
    return str;
  }
  return str;
}
export const validatezero = (rule, value, callback) => {
  if (value && value * 1 === 0) {
    callback(new Error(`不得设置为0`));
  } else if (value * 1 < 0) {
    callback(new Error(`不得设置为负数`));
  } else if (value % 1 !== 0) {
    callback(new Error(`请设置为整数`));
  } else {
    callback();
  }
};
export const validateCoin = async (rule, value, callback) => {
  await reqeustPayInfo();
  console.log(
    rule,
    value,
    callback,
    newpayInfo,
    new_play_ids.indexOf(rule.playlet_id) !== -1,
    new_play_ids,
    '>>>>>>>>>>>>>>>>>>>>>>',
  );
  let flag = false;
  if (rule.visibelType) {
    rule.playlet_id.forEach((item) => {
      new_play_ids.indexOf(item * 1) != -1 ? (flag = true) : '';
    });
  }
  if (new_play_ids.indexOf(rule.playlet_id * 1) != -1 || flag) {
    if (Number(value) < newpayInfo.single) {
      callback(new Error(`单集定价需在${newpayInfo.single}~ ${newpayInfo.single_max}虚拟币之间`));
    } else if (newpayInfo.single_max && Number(value) > newpayInfo.single_max) {
      callback(new Error(`单集定价需在${newpayInfo.single}~ ${newpayInfo.single_max}虚拟币之间`));
    } else {
      callback();
    }
  } else if (Number(value) < oldpayInfo.single) {
    callback(new Error(`单集定价需在${oldpayInfo.single}~ ${oldpayInfo.single_max}虚拟币之间`));
  } else if (oldpayInfo.single_max && Number(value) > oldpayInfo.single_max) {
    callback(new Error(`单集定价需在${oldpayInfo.single}~ ${oldpayInfo.single_max}虚拟币之间`));
  } else {
    callback();
  }
};
export const validateStart = (rule, value, callback) => {
  if (Number(value) > 60) {
    callback(new Error('起始收费不得大于60集'));
  } else {
    callback();
  }
};
export const validateDiscount = async (rule, value, callback) => {
  await reqeustPayInfo();
  if (oldpayInfo.discount && oldpayInfo.discount !== '') {
    if (Number(value) < Number(oldpayInfo.discount)) {
      callback(new Error(`折扣不能小于${oldpayInfo.discount}`));
    } else if (Number(value) < 1) {
      callback(new Error(`折扣不能小于1`));
    } else if (Number(value) > 9.9) {
      callback(new Error(`折扣不能大于9.9`));
    } else {
      callback();
    }
  } else if (Number(value) < 1 || Number(value) > 9.9) {
    callback(new Error(`折扣在1到9.9之间`));
  } else {
    callback();
  }
};
export const validateDiscountInput = (rule, value, callback) => {
  if (Number(value) < 1 || Number(value) > 9.9) {
    callback(new Error(`折扣在1到9.9之间`));
  }
};

export function downloadVideo(row, _this) {
  console.log(row);
  downloadPlaylet({ chapter_id: row.chapter_id }).then((res) => {
    if (res.status_code === 1) {
      let title = '';
      if (row.title) {
        title = `${row.title}第${row.chapter_num}集.mp4`;
      } else if (row.chapter_title) {
        title = `${row.chapter_title}.mp4`;
      } else {
        title = `${row.chapter_num}.mp4`;
      }
      downloadfile(res.data.down_url, title);
    } else {
      _this.$message.warning('下载失败');
    }
  });
}

/*
 * 使用download.js 强制浏览器下载图片、视频等文件
 * @param {any} url url链接地址
 * @param {any} strFileName 文件名
 * @param {any} strMimeType 文件类型
 * dzl
 * 2020年5月8日
 */
// export function downloadfile(url) {
//   var xmlHttp = null
//   if (window.ActiveXObject) {
//     // IE6, IE5 浏览器执行代码
//     xmlHttp = new ActiveXObject('Microsoft.XMLHTTP')
//   } else if (window.XMLHttpRequest) {
//     // IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
//     xmlHttp = new XMLHttpRequest()
//   }
//   // 2.如果实例化成功，就调用open（）方法：
//   if (xmlHttp != null) {
//     xmlHttp.open('get', 'https://zyucdn.wozhangwan.com/playlet-test/1687916191462_f33c5e0844.mp4?auth_key=1689672184-89733472-0-7193672788a84e69f709a8fdd3959aec', true)
//     xmlHttp.responseType = 'blob'// 关键
//     xmlHttp.send()
//     xmlHttp.onreadystatechange = doResult // 设置回调函数
//   }
//   function doResult() {
//     if (xmlHttp.readyState == 4) { // 4表示执行完成
//       if (xmlHttp.status == 200) { // 200表示执行成功
//         download(xmlHttp.response, 'strFileName', 'video')
//       }
//     }
//   }
// }

// export function downloadfile(url, title) {
//   const abortController = new AbortController()
//   return fetch(url, {
//     headers: { 'Content-Type': 'application/octet-stream' },
//     signal: abortController.signal
//   }).then(res => {
//     const fileStream = window.streamSaver.createWriteStream(title, {
//       size: res.headers.get('content-length')
//     })
//     const readableStream = res.body
//     if (window.WritableStream && readableStream.pipeTo) {
//       return readableStream.pipeTo(fileStream).then(() => console.log('done writing'))
//     }
//     window.writer = fileStream.getWriter()
//     const reader = res.body.getReader()
//     const pump = () => reader.read().then(res => res.done ? window.writer.close() : window.writer.write(res.value).then(pump))
//     pump()
//   })
// }

export function copyText(className, that) {
  const clipboard = new Clipboard(className);
  clipboard.on('success', (e) => {
    that.$message.success('复制成功');
    // 释放内存
    clipboard.destroy();
  });
}

export async function downloadfile(url, title) {
  const abortController = new AbortController();
  try {
    const res = await fetch(url, {
      headers: { 'Content-Type': 'application/octet-stream' },
      signal: abortController.signal,
    });
    const size = Number(res.headers.get('content-length'));
    let loaded = 0;
    const fileStream = streamSaver.createWriteStream(title, {
      size,
    });
    const readableStream = res.body;

    if (window.WritableStream && readableStream.pipeTo) {
      const startTime = performance.now();

      const progress = new TransformStream({
        transform(chunk, controller) {
          loaded += chunk.length;
          // onProgress(loaded, size, startTime)
          controller.enqueue(chunk);
        },
      });

      await readableStream.pipeThrough(progress).pipeTo(fileStream);
    }
  } catch (error) {
    console.error(error);
  }
}
export function reqeustPayInfo() {
  return new Promise((resolve, reject) => {
    paymentList({ type: 1, app_type: store.state.user.routerItem.app_type || '' }).then(
      (res) => {
        if (res.data.data && res.data.data.limit_config) {
          oldpayInfo = res.data.data.limit_config;
        }
      },
      (err) => {
        reject(err);
      },
    );
    paymentList({ type: 2, app_type: store.state.user.routerItem.app_type || '' }).then(
      (res) => {
        resolve(res);
        if (res.data.data && res.data.data.limit_config) {
          newpayInfo = res.data.data.limit_config;
          new_play_ids = res.data.data.playlet_id.map((item) => item * 1);
        }
      },
      (err) => {
        reject(err);
      },
    );
  });
}
export function setPayInfo(data) {
  oldpayInfo = {};
  newpayInfo = {};
  new_play_ids = [];
}

// rule 收费规则 ， template 充值模版 ， initial 初始定价 ， start 收费起始集 ，total 总共多少集
export const consumption = (rule, template, initial, start, total) => {
  const arr = [];
  if (rule.length > 0) {
    template.forEach((item) => {
      if (item.product_type == 1) {
        let coin = item.coin * 1 + item.free_coin * 1;
        // console.log(coin, '共多少币')
        const look_num = start;
        for (let index = look_num; index <= total; index++) {
          if (rule[rule.length - 1].end_chapter >= index && index >= rule[0].start_chapter) {
            let flag = false;
            rule.forEach((it, ind) => {
              if (index >= it.start_chapter && index <= it.end_chapter) {
                if (coin >= it.step_coin) {
                  coin -= it.step_coin;
                  // console.log(coin, '剩余多少', '本次扣', it.step_coin, '第几集', index)
                } else {
                  arr.push({
                    rechargeType: item.product_name,
                    details: `充${item.amount}元(${item.coin}喵币),送${item.free_coin}增币`,
                    results: `第${index - 1}集,剩余喵币${coin}`,
                  });
                  flag = true;
                }
              }
            });
            if (flag) {
              break;
            }
          } else if (coin >= initial) {
            coin -= initial;
            // console.log(coin, '剩余多少', '本次扣', initial, '第几集', index)
          } else {
            arr.push({
              rechargeType: item.product_name,
              details: `充${item.amount}元(${item.coin}喵币),送${item.free_coin}增币`,
              results: `第${index - 1}集,剩余喵币${coin}`,
            });
            break;
          }
          // console.log(index, total)
          if (index == total) {
            arr.push({
              rechargeType: item.product_name,
              details: `充${item.amount}元(${item.coin}喵币),送${item.free_coin}增币`,
              results: `全集${index}集,剩余喵币${coin}`,
            });
          }
        }
      } else if (item.product_type == 11) {
        arr.push({
          rechargeType: item.product_name,
          details: '-',
          results: `${item.chapter_count > total ? `全集${total}` : `第${item.chapter_count}`}集`,
        });
      } else {
        arr.push({
          rechargeType: item.product_name,
          details: '-',
          results: `全集${total}集`,
        });
      }
    });
  } else {
    template.forEach((item) => {
      if (item.product_type == 1) {
        let coin = item.coin * 1 + item.free_coin * 1;
        // console.log(coin, '共多少币')
        const look_num = start;
        for (let index = look_num; index <= total; index++) {
          if (coin >= initial) {
            coin -= initial;
            // console.log(coin, '剩余多少', '本次扣', initial, '第几集', index)
          } else {
            arr.push({
              rechargeType: item.product_name,
              details: `充${item.amount}元(${item.coin}喵币),送${item.free_coin}增币`,
              results: `第${index - 1}集,剩余喵币${coin}`,
            });
            break;
          }
          if (index == total) {
            arr.push({
              rechargeType: item.product_name,
              details: `充${item.amount}元(${item.coin}喵币),送${item.free_coin}增币`,
              results: `全集${index}集,剩余喵币${coin}`,
            });
          }
        }
      } else if (item.product_type == 11) {
        arr.push({
          rechargeType: item.product_name,
          details: '-',
          results: `${item.chapter_count > total ? `全集${total}` : `第${item.chapter_count}`}集`,
        });
      } else {
        arr.push({
          rechargeType: item.product_name,
          details: '-',
          results: `全集${total}集`,
        });
      }
    });
  }
  return arr;
};
export function getDecimalPlace(num) {
  const numStr = num.toString();
  const dotIndex = numStr.indexOf('.');
  if (dotIndex === -1) {
    return 0;
  }
  return numStr.length - dotIndex - 1;
}
export function checkMoney(value) {
  if (value > 0) {
    value = value.toString();
    // 价格的限制规则，只能输入小数点后两位
    value = value.replace(/[^\d.]/g, ''); // 清除"数字"和"."以外的字符
    value = value.replace(/^\./g, ''); // 验证第一个字符是数字而不是字符
    value = value.replace(/\.{2,}/g, '.'); // 只保留第一个.清除多余的
    value = value.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.');
    value = value.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3'); // 只能输入两个小数
    return value;
  }
}
export function numWay(str) {
  if (str.indexOf('.') == -1) {
    return `${str}.00`;
  }
  const tow = str.split('.')[1];
  if (tow.length < 2) {
    return `${str}0`;
  }
  return str;
}

export function numFormat(num) {
  return num.toString().replace(/\d+/, function (n) {
    // 先提取整数部分
    return n.replace(/(\d)(?=(\d{3})+$)/g, function ($1) {
      return `${$1},`;
    });
  });
}

export function numberFormatThousandthPercentile(num) {
  if (!num) {
    return num;
  }
  try {
    return Math.round(num).toLocaleString();
  } catch (error) {
    return num;
  }
}

function normalizeStringPosix(path, allowAboveRoot) {
  let res = '';
  let lastSegmentLength = 0;
  let lastSlash = -1;
  let dots = 0;
  let code;
  for (let i = 0; i <= path.length; ++i) {
    if (i < path.length) code = path.charCodeAt(i);
    else if (code === 47 /* / */) break;
    else code = 47 /* / */;
    if (code === 47 /* / */) {
      if (lastSlash === i - 1 || dots === 1) {
        // NOOP
      } else if (lastSlash !== i - 1 && dots === 2) {
        if (
          res.length < 2 ||
          lastSegmentLength !== 2 ||
          res.charCodeAt(res.length - 1) !== 46 /* . */ ||
          res.charCodeAt(res.length - 2) !== 46 /* . */
        ) {
          if (res.length > 2) {
            const lastSlashIndex = res.lastIndexOf('/');
            if (lastSlashIndex !== res.length - 1) {
              if (lastSlashIndex === -1) {
                res = '';
                lastSegmentLength = 0;
              } else {
                res = res.slice(0, lastSlashIndex);
                lastSegmentLength = res.length - 1 - res.lastIndexOf('/');
              }
              lastSlash = i;
              dots = 0;
              continue;
            }
          } else if (res.length === 2 || res.length === 1) {
            res = '';
            lastSegmentLength = 0;
            lastSlash = i;
            dots = 0;
            continue;
          }
        }
        if (allowAboveRoot) {
          if (res.length > 0) res += '/..';
          else res = '..';
          lastSegmentLength = 2;
        }
      } else {
        if (res.length > 0) res += `/${path.slice(lastSlash + 1, i)}`;
        else res = path.slice(lastSlash + 1, i);
        lastSegmentLength = i - lastSlash - 1;
      }
      lastSlash = i;
      dots = 0;
    } else if (code === 46 /* . */ && dots !== -1) {
      ++dots;
    } else {
      dots = -1;
    }
  }
  return res;
}

/**
 * link 代码来源 path-browserify@1.0.1 包
 * @returns
 */
export function resolve() {
  let resolvedPath = '';
  let resolvedAbsolute = false;
  let cwd;

  for (let i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
    var path;
    if (i >= 0) path = arguments[i];
    else if (cwd === undefined)
      // cwd = process.cwd();
      path = '';

    // Skip empty entries
    if (path.length === 0) {
      continue;
    }

    resolvedPath = `${path}/${resolvedPath}`;
    resolvedAbsolute = path.charCodeAt(0) === 47 /* / */;
  }

  // At this point the path should be resolved to a full absolute path, but
  // handle relative paths to be safe (might happen when process.cwd() fails)

  // Normalize the path
  resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute);

  if (resolvedAbsolute) {
    if (resolvedPath.length > 0) return `/${resolvedPath}`;
    return '/';
  }
  if (resolvedPath.length > 0) {
    return resolvedPath;
  }
  return '.';
}
